// situation_wrapper.h
// Written by Kevin Sonnen, Sam Tarin, and Andi Cescolini

#ifndef SITUATION_WRAPPER_H
#define SITUATION_WRAPPER_H
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "../situationControl/Situation.h"
//#define DEBUG

namespace sit_wrap {
class situation_wrapper {
public:
  enum { header_length = 4 };
  enum { max_body_length = 512 };
  situation_wrapper()
    : body_length_(0)
  {
  }
  situation_wrapper(Situation mSit)
    : body_length_(0)
  {
	sit_.setPlayer(mSit.getPlayer());
	sit_.setOpponent(mSit.getOpponent());
	sit_.setRoom(mSit.getRoom());

  }
  void serialize()
  {
    std::ostringstream archive_stream;
    boost::archive::text_oarchive archive(archive_stream);
    archive << sit_;
    std::string outbound_data;
    outbound_data = archive_stream.str();
    memcpy(body(), outbound_data.c_str(), outbound_data.size());

    body_length(outbound_data.size());

    #ifdef DEBUG
    std::cout << "data from serializer " << outbound_data.c_str() << std::endl;
    std::cout << "data after memcopy " << data_ << std::endl;
    #endif

  }
  Situation deserialize()
  {
    #ifdef DEBUG
    std::cout<< "printing data in deserialize" << data_ << std::endl;
    std::cout<< "printing body() in deserialize" << body() << std::endl;
    #endif
    std::string archive_data(body());
    std::istringstream archive_stream(archive_data);
    boost::archive::text_iarchive archive(archive_stream);
    #ifdef DEBUG
    printf("made it past archive stuff\n"); 
    #endif
    archive >> sit_;

    return sit_;
  }
  const Situation situation() const
  {
    return sit_;
  }
  const char* data() const
  {
    return data_;
  }
  char* data()
  {
    return data_;
  }
  size_t length() const
  {
    return header_length + body_length_;
  }
  const char* body() const
  {
    return data_ + header_length;
  }
  char* body()
  {
    return data_ + header_length;
  }
  size_t body_length() const
  {
    return body_length_;
  }
  void body_length(size_t new_length)
  {
    body_length_ = new_length;
    if (body_length_ > max_body_length)
      body_length_ = max_body_length;
  }
  bool decode_header()
  {
    using namespace std; // For strncat and atoi.
    char header[header_length + 1] = "";
    strncat(header, data_, header_length);
    body_length_ = atoi(header);
    if (body_length_ > max_body_length)
    {
      body_length_ = 0;
      return false;
    }
    return true;
  }
  void encode_header()
  {
    using namespace std; // For sprintf and memcpy.
    char header[header_length + 1] = "";
    //printf("%4d\n", body_length_);
    sprintf(header, "%4d", body_length_);
    memcpy(data_, header, header_length);
  }
private:
  char data_[header_length + max_body_length];  // Serialized situation and header
  size_t body_length_;
  Situation sit_;
};
}       // End of namespace sit_wrap
#endif // SITUATION_WRAPPER_H
